package edu.istu.asu07_1.live.model.agents.controller;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import edu.istu.asu07_1.live.configs.Constants;

/**
 * Нейроконтроллер, управляющий поведением агента
 * @author romanches
 *
 */
public class NeuralController {

	//	Матрица весов нейронной сети
	//	Структура матрицы:
	//	съесть = [хищ.справа] [трав.справа] [раст.справа] [хищ.вперед.] [трав.вперед] [раст.вперед.] [хищ.слев.] [трав.слев] [раст.слев] [хищ.близ.] [трав.близ] [раст.близ]
	//	направо= [хищ.справа] [трав.справа] [раст.справа] [хищ.вперед.] [трав.вперед] [раст.вперед.] [хищ.слев.] [трав.слев] [раст.слев] [хищ.близ.] [трав.близ] [раст.близ]
	//	прямо  = [хищ.справа] [трав.справа] [раст.справа] [хищ.вперед.] [трав.вперед] [раст.вперед.] [хищ.слев.] [трав.слев] [раст.слев] [хищ.близ.] [трав.близ] [раст.близ]
	//	налево = [хищ.справа] [трав.справа] [раст.справа] [хищ.вперед.] [трав.вперед] [раст.вперед.] [хищ.слев.] [трав.слев] [раст.слев] [хищ.близ.] [трав.близ] [раст.близ]
	private int[][] weightMatrix;
	//	вектор смещений для каждого перцептрона сети
	//	структура матрицы:
	//	[смещение съесть] [смещение направо] [смещение прямо] [смещение налево]
	private int[] shiftVector;
	//	Коллекция с результатоми решения нейронной сети
	private List results = new ArrayList();
	//	Коэффициенты, соответствующие выходам нейронной сети
	private int eatCoefficient;
	private int rightCoefficient;
	private int forwardCoefficient;
	private int leftCoefficient;

	public NeuralController(int[][] weightMatrix, int[] shiftVector) {
		this.weightMatrix = weightMatrix;
		this.shiftVector = shiftVector;
	}

	public NeuralController getMutateController(){
//		return new NeuralController(Constants.HERBIVORE_WEIGHT_MATRIX, Constants.HERBIVORE_SHIFT_VECTOR);
		return this;
	}


	public int getAction(int[] inputs){
		results.clear();

		//magic
		eatCoefficient = shiftVector[0];
		for(int i=0; i<inputs.length; i++){
			eatCoefficient += inputs[i]*weightMatrix[0][i];
		}

		rightCoefficient = shiftVector[1];
		for(int i=0; i<inputs.length; i++){
			rightCoefficient += inputs[i]*weightMatrix[1][i];
		}

		forwardCoefficient = shiftVector[2];
		for(int i=0; i<inputs.length; i++){
			forwardCoefficient += inputs[i]*weightMatrix[2][i];
		}

		leftCoefficient = shiftVector[3];
		for(int i=0; i<inputs.length; i++){
			leftCoefficient += inputs[i]*weightMatrix[3][i];
		}
//		System.out.println("eat "+eatCoefficient);
//		System.out.println("left "+leftCoefficient);
//		System.out.println("forward "+forwardCoefficient);
//		System.out.println("right "+rightCoefficient);

		results.add(eatCoefficient);
		results.add(rightCoefficient);
		results.add(forwardCoefficient);
		results.add(leftCoefficient);

		Collections.sort(results);
//		Победитель получает все
		if((Integer)results.get(3) == eatCoefficient){
			return EAT;
		}else if((Integer)results.get(3) == rightCoefficient){
			return TURN_RIGHT;
		}else if((Integer)results.get(3) == forwardCoefficient){
			return MOUVE_FORWARD;
		}else if((Integer)results.get(3) == leftCoefficient){
			return TURN_LEFT;
		}
		return 0;
	}

	public static final int EAT = 0;
	public static final int TURN_RIGHT = 1;
	public static final int MOUVE_FORWARD = 2;
	public static final int TURN_LEFT = 3;
}
